using System;
using System.Timers;
using BuildStatusIndicator.Controller;
using BuildStatusIndicator.Controller.EventBroker;
using BuildStatusIndicator.Controller.Events;
using Microsoft.TeamFoundation.Build.Client;

namespace BuildStatusIndicator.ControllerTests.Stubs
{
    public class ControllerStub : IController
    {
        private readonly IBuildStatusEventPublisher _publisher;
        private readonly Timer _timer;
        private bool _connected;

        public ControllerStub(IBuildStatusEventPublisher eventPublisher)
        {
            _publisher = eventPublisher;
            _timer = new Timer(5000);
        }

        #region IController Members

        public void Dispose()
        {
            if (_connected)
            {
                Disconnect();
            }
        }

        #endregion

        private void TimerElapsed(object sender, ElapsedEventArgs e)
        {
            CreateBuildEvent(e.SignalTime);
        }

        private void CreateBuildEvent(DateTime time)
        {
            var server = new TfsBuildServerStub();

            int mod = time.Second%6;
            switch (mod)
            {
                case 0:
                    _publisher.PublishEvent(
                        new BuildFailedEvent(new TfsBuildDetailStub
                                                 {
                                                     BuildNumber = mod.ToString(),
                                                     Status = BuildStatus.Failed,
                                                     RequestedFor = "Me",
                                                     FinishTime = time,
                                                     TestStatus = BuildPhaseStatus.Unknown,
                                                     BuildServer = server
                                                 }));
                    break;
                case 1:
                    _publisher.PublishEvent(
                        new BuildFailedEvent(new TfsBuildDetailStub
                                                 {
                                                     BuildNumber = mod.ToString(),
                                                     Status = BuildStatus.Failed,
                                                     RequestedFor = "Me",
                                                     FinishTime = time,
                                                     TestStatus = BuildPhaseStatus.Failed,
                                                     BuildServer = server
                                                 }));
                    break;
                case 2:
                    _publisher.PublishEvent(
                        new BuildSucceededEvent(new TfsBuildDetailStub
                                                    {
                                                        BuildNumber = mod.ToString(),
                                                        Status = BuildStatus.Succeeded,
                                                        RequestedFor = "Me",
                                                        FinishTime = time,
                                                        BuildServer = server
                                                    }));
                    break;
                default:
                    _publisher.PublishEvent(
                        new BuildInProgressEvent(new TfsBuildDetailStub
                                                     {
                                                         BuildNumber = mod.ToString(),
                                                         Status = BuildStatus.InProgress,
                                                         RequestedFor = "Me",
                                                         FinishTime = time,
                                                         BuildServer = server
                                                     }));
                    break;
            }
        }

        #region Implementation of IController

        public void Connect()
        {
            CreateBuildEvent(DateTime.Now);
            _timer.Enabled = true;
            _timer.Elapsed += TimerElapsed;
            _publisher.PublishEvent(new BuildNotificationStartingEvent());
            _connected = true;
        }

        public void Disconnect()
        {
            _timer.Elapsed -= TimerElapsed;
            _timer.Enabled = false;
            _publisher.PublishEvent(new BuildNotificationEndingEvent());
            _connected = false;
        }

        #endregion
    }
}